#include "MainWindow.h"

#include "model/UMLDiagram.h"
#include "controller/DiagramFam.h"
#include "controller/ModifyTextCmd.h"

#include <QMenu>
#include <QMenuBar>
#include <QDockWidget>
#include <QTextEdit>
#include <QApplication> // for quitting the app

MainWindow::MainWindow(QWidget *parent)
:	QMainWindow(parent),
	_dman(this), _tman(_dman, this),  // safe because they take QWidget*, base
	_editing(NULL)
	 // _textEdit will be initialized by createTextEdit()
{
	/* Create UI elements */

	setCentralWidget(_dman.display());

	createMenus();
	createPalette();
	createTextEdit();

	/* Hook up */

	connect(&_dman, SIGNAL(activeChanged(DiagramFam*)),
			SLOT(onActiveChanged(DiagramFam*)));
	connect(_textEdit, SIGNAL(textChanged()), SLOT(onTextChanged()));

	/* Setup initial diagram */

	UMLDiagram* diagram = new UMLDiagram;

	_dman.add(diagram);
	diagram = NULL; // we don't own the pointer anymore
}

void MainWindow::newDiagram()
{
	_dman.add(new UMLDiagram);
}

void MainWindow::onActiveChanged(DiagramFam* newfam)
{
	/* The logic here is that we stay connected to every DiagramFam* we've seen.
	 * We disconnect in two cases:
	 * 1) When connect, to prevent duplicate connections.
	 * 2) Implicitly, when a DiagramFam/UMLCanvas is destroyed.
	 *
	 * Staying connected to old UMLCanvases is fine because there's no way
	 * selection will be changed without user interaction.
	 */

	if (newfam)
	{
		// remove old connection(s)
		newfam->canvas().disconnect(SIGNAL(selectionChanged(UMLObject*)), this);
		// restore it
		connect(&newfam->canvas(), SIGNAL(selectionChanged(UMLObject*)),
				SLOT(edit(UMLObject*)));
	}

	// ALWAYS clear this to avoid dangling pointers.
	edit(NULL);
}

void MainWindow::edit(UMLObject* object)
{
	_editing = object;

	if (object)
		_textEdit->setPlainText(object->text().fullText());
	else
		_textEdit->clear();
}

void MainWindow::onTextChanged()
{
	if (_editing)
	{
		ModifyTextCmd c(_editing, _textEdit->toPlainText());
		_dman.active().acceptor().accept(c, true);
		// TODO: send final command when focus leaves
	}
}

void MainWindow::createMenus()
{
	QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
	// TODO: add keyboard shortcuts
	fileMenu->addAction(tr("&New"), this, SLOT(newDiagram()),
			QKeySequence(QKeySequence::New));
	fileMenu->addAction(tr("E&xit"), qApp, SLOT(quit()));
}

void MainWindow::createPalette()
{
	QDockWidget *dock = new QDockWidget(tr("UML Palette"), this);

	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	dock->setWidget(_tman.palette());

	// TODO: don't allow closing

	addDockWidget(Qt::RightDockWidgetArea, dock);
}

void MainWindow::createTextEdit()
{
	QDockWidget *dock = new QDockWidget(tr("Properties"), this);
	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

	_textEdit = new QTextEdit(dock);
	dock->setWidget(_textEdit);

	// TODO: don't allow closing
	
	addDockWidget(Qt::RightDockWidgetArea, dock);
}

